package com.fancy.playlist.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fancy.common.dto.*;
import com.fancy.common.dto.response.Result;
import com.fancy.imasclient.client.ArtistServiceClient;
import com.fancy.imasclient.client.MusicServiceClient;
import com.fancy.imasclient.client.PlaylistServiceClient;
import com.fancy.playlist.entity.UserCollection;
import com.fancy.playlist.mapper.UserCollectionMapper;
import com.fancy.playlist.service.UserCollectionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserCollectionServiceImpl implements UserCollectionService {

    private final UserCollectionMapper userCollectionMapper;
    private final MusicServiceClient musicServiceClient;
    private final ArtistServiceClient artistServiceClient;
    private final PlaylistServiceClient playlistServiceClient;

    @Override
    public PageResult<UserCollectionResponseDTO> getUserCollections(Long userId, Integer type, int page, int size) {
        Page<UserCollection> pageRequest = new Page<>(page, size);
        QueryWrapper<UserCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        if (type != null) {
            queryWrapper.eq("target_type", type);
        }
        queryWrapper.orderByDesc("create_time");

        Page<UserCollection> pageResult = userCollectionMapper.selectPage(pageRequest, queryWrapper);
        List<UserCollection> collections = pageResult.getRecords();

        if (collections.isEmpty()) {
            return new PageResult<>(Collections.emptyList(), 0L);
        }

        List<UserCollectionResponseDTO> dtos = enrichCollections(collections);

        return new PageResult<>(dtos, pageResult.getTotal());
    }

    private List<UserCollectionResponseDTO> enrichCollections(List<UserCollection> collections) {
        List<UserCollectionResponseDTO> result = new ArrayList<>();

        // 按目标类型分组
        Map<Integer, List<UserCollection>> groupedByType = collections.stream()
                .collect(Collectors.groupingBy(UserCollection::getTargetType));

        // 处理歌曲收藏 (target_type = 1)
        List<UserCollection> songCollections = groupedByType.get(1);
        if (songCollections != null && !songCollections.isEmpty()) {
            result.addAll(enrichSongCollections(songCollections));
        }

        // 处理专辑收藏 (target_type = 2)
        List<UserCollection> albumCollections = groupedByType.get(2);
        if (albumCollections != null && !albumCollections.isEmpty()) {
            result.addAll(enrichAlbumCollections(albumCollections));
        }

        // 处理歌单收藏 (target_type = 3)
        List<UserCollection> playlistCollections = groupedByType.get(3);
        if (playlistCollections != null && !playlistCollections.isEmpty()) {
            result.addAll(enrichPlaylistCollections(playlistCollections));
        }

        // 处理歌手收藏 (target_type = 4)
        List<UserCollection> artistCollections = groupedByType.get(4);
        if (artistCollections != null && !artistCollections.isEmpty()) {
            result.addAll(enrichArtistCollections(artistCollections));
        }

        // 按创建时间倒序排序
        result.sort((a, b) -> b.getCreateTime().compareTo(a.getCreateTime()));

        return result;
    }

    private List<UserCollectionResponseDTO> enrichSongCollections(List<UserCollection> collections) {
        List<Long> songIds = collections.stream()
                .map(UserCollection::getTargetId)
                .collect(Collectors.toList());

        try {
            Result<List<SongBasicInfo>> result = musicServiceClient.getSongBasicInfoBatch(songIds);
            if (result.isSuccess() && result.getData() != null) {
                Map<Long, SongBasicInfo> songMap = result.getData().stream()
                        .collect(Collectors.toMap(SongBasicInfo::getSongId, song -> song));

                return collections.stream().map(collection -> {
                    UserCollectionResponseDTO dto = convertToDTO(collection);
                    SongBasicInfo song = songMap.get(collection.getTargetId());
                    if (song != null) {
                        dto.setTargetName(song.getSongName());
                        dto.setTargetCoverUrl(song.getCoverUrl());
                        dto.setArtistName(song.getArtistName());
                        dto.setDuration(formatDuration(song.getDuration()));
                    }
                    return dto;
                }).collect(Collectors.toList());
            }
        } catch (Exception e) {
            log.error("获取歌曲信息失败", e);
        }

        return collections.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    private List<UserCollectionResponseDTO> enrichAlbumCollections(List<UserCollection> collections) {
        List<Long> albumIds = collections.stream()
                .map(UserCollection::getTargetId)
                .collect(Collectors.toList());

        try {
            Result<List<AlbumBasicInfo>> result = musicServiceClient.getAlbumBasicInfoBatch(albumIds);
            if (result.isSuccess() && result.getData() != null) {
                Map<Long, AlbumBasicInfo> albumMap = result.getData().stream()
                        .collect(Collectors.toMap(AlbumBasicInfo::getAlbumId, album -> album));

                return collections.stream().map(collection -> {
                    UserCollectionResponseDTO dto = convertToDTO(collection);
                    AlbumBasicInfo album = albumMap.get(collection.getTargetId());
                    if (album != null) {
                        dto.setTargetName(album.getAlbumName());
                        dto.setTargetCoverUrl(album.getCoverUrl());
                        dto.setArtistName(album.getArtistName());
                        dto.setSongCount(album.getTrackCount());
                        dto.setTargetDescription(album.getDescription());
                    }
                    return dto;
                }).collect(Collectors.toList());
            }
        } catch (Exception e) {
            log.error("获取专辑信息失败", e);
        }

        return collections.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    private List<UserCollectionResponseDTO> enrichPlaylistCollections(List<UserCollection> collections) {
        List<Long> playlistIds = collections.stream()
                .map(UserCollection::getTargetId)
                .collect(Collectors.toList());

        try {
            Result<List<PlaylistBasicInfo>> result = playlistServiceClient.getPlaylistBasicInfoBatch(playlistIds);
            if (result.isSuccess() && result.getData() != null) {
                Map<Long, PlaylistBasicInfo> playlistMap = result.getData().stream()
                        .collect(Collectors.toMap(PlaylistBasicInfo::getPlaylistId, playlist -> playlist));

                return collections.stream().map(collection -> {
                    UserCollectionResponseDTO dto = convertToDTO(collection);
                    PlaylistBasicInfo playlist = playlistMap.get(collection.getTargetId());
                    if (playlist != null) {
                        dto.setTargetName(playlist.getPlaylistName());
                        dto.setTargetCoverUrl(playlist.getCoverUrl());
                        dto.setTargetDescription(playlist.getDescription());
                        dto.setSongCount(playlist.getSongCount());
                    }
                    return dto;
                }).collect(Collectors.toList());
            }
        } catch (Exception e) {
            log.error("获取歌单信息失败", e);
        }

        return collections.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    private List<UserCollectionResponseDTO> enrichArtistCollections(List<UserCollection> collections) {
        List<Long> artistIds = collections.stream()
                .map(UserCollection::getTargetId)
                .collect(Collectors.toList());

        try {
            Result<List<ArtistBasicInfo>> result = artistServiceClient.getArtistBasicInfoBatch(artistIds);
            if (result.isSuccess() && result.getData() != null) {
                Map<Long, ArtistBasicInfo> artistMap = result.getData().stream()
                        .collect(Collectors.toMap(ArtistBasicInfo::getArtistId, artist -> artist));

                return collections.stream().map(collection -> {
                    UserCollectionResponseDTO dto = convertToDTO(collection);
                    ArtistBasicInfo artist = artistMap.get(collection.getTargetId());
                    if (artist != null) {
                        dto.setTargetName(artist.getArtistName());
                        dto.setTargetCoverUrl(artist.getAvatarUrl());
                        dto.setTargetDescription(artist.getIntroduction());
                    }
                    return dto;
                }).collect(Collectors.toList());
            }
        } catch (Exception e) {
            log.error("获取歌手信息失败", e);
        }

        return collections.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    private UserCollectionResponseDTO convertToDTO(UserCollection collection) {
        UserCollectionResponseDTO dto = new UserCollectionResponseDTO();
        dto.setId(collection.getId());
        dto.setUserId(collection.getUserId());
        dto.setTargetId(collection.getTargetId());
        dto.setTargetType(collection.getTargetType());
        dto.setCreateTime(collection.getCreateTime());
        return dto;
    }

    private String formatDuration(Integer seconds) {
        if (seconds == null || seconds <= 0) {
            return "00:00";
        }
        int minutes = seconds / 60;
        int remainingSeconds = seconds % 60;
        return String.format("%02d:%02d", minutes, remainingSeconds);
    }

    @Override
    public int getCollectionCount(Long userId) {
        return userCollectionMapper.selectCount(new QueryWrapper<UserCollection>().eq("user_id", userId)).intValue();
    }

    @Override
    public boolean addCollection(Long userId, Long targetId, Integer targetType) {
        try {
            UserCollection existing = userCollectionMapper.selectOne(
                new QueryWrapper<UserCollection>()
                    .eq("user_id", userId)
                    .eq("target_id", targetId)
                    .eq("target_type", targetType)
            );

            if (existing != null) {
                return false; // 已经收藏过了
            }

            UserCollection collection = new UserCollection();
            collection.setUserId(userId);
            collection.setTargetId(targetId);
            collection.setTargetType(targetType);
            collection.setCreateTime(new Date());

            return userCollectionMapper.insert(collection) > 0;
        } catch (Exception e) {
            log.error("添加收藏失败", e);
            return false;
        }
    }

    @Override
    public boolean removeCollection(Long userId, Long targetId, Integer targetType) {
        try {
            QueryWrapper<UserCollection> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                       .eq("target_id", targetId)
                       .eq("target_type", targetType);

            return userCollectionMapper.delete(queryWrapper) > 0;
        } catch (Exception e) {
            log.error("取消收藏失败", e);
            return false;
        }
    }

    @Override
    public boolean isCollected(Long userId, Long targetId, Integer targetType) {
        try {
            QueryWrapper<UserCollection> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId)
                       .eq("target_id", targetId)
                       .eq("target_type", targetType);

            return userCollectionMapper.selectCount(queryWrapper) > 0;
        } catch (Exception e) {
            log.error("检查收藏状态失败", e);
            return false;
        }
    }
}
